package client // Package client import "xemo.top/docker/docker/client"
import (
	"context"
	"net/http"
	"path"
	"xemo.top/docker/docker/api/types"
)

// Ping 对服务器执行pings操作，并返回 “Docker-expendered” 、 “Builder-Version” 、 “OS-Type” 和 “api-version” 标头的值。它尝试在端点上使用HEAD请求，但如果守护进程不支持HEAD，则返回GET。
// Ping pings the server and returns the value of the "Docker-Experimental","Builder-Version","OS-Type" & "API-Version" headers.It attempts to use a HEAD request on the endpoint, but fails back to GET if HEAD is not supported by the daemon.
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
	var ping types.Ping
	// 使用cli.buildRequest() cli.doRequest() 而不是cli.sendRequest()，因为在API版本协商期间使用ping请求，所以我们要点击非版本化/_ping端点，而不是/v1.xx/_ping
	// Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest() because ping requests are used during API version negotiation,so we want to hit the non-versioned /_ping endpoint,not /v1.xx/_ping
	req, err := cli.buildRequest("HEAD", path.Join(cli.basePath, "/_ping"), nil, nil)
	if err != nil {
		return ping, err
	}
	serverResp, err := cli.doRequest(ctx, req)
	if err == nil {
		defer ensureReaderClosed(serverResp)
		switch serverResp.statusCode {
		case http.StatusOK, http.StatusInternalServerError:
			// Server handled the request, so parse the response
			return parsePingResponse(cli, serverResp)
		}
	} else if IsErrConnectionFailed(err) {
		return ping, err
	}
	req, err = cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
	if err != nil {
		return ping, err
	}
	serverResp, err = cli.doRequest(ctx, req)
	defer ensureReaderClosed(serverResp)
	if err != nil {
		return ping, err
	}
	return parsePingResponse(cli, serverResp)
}
